

#include <gfx/gl20/indexbuffer_gl15.h>

static GLuint current_mapped_buffer = 0;


ceIndexBufferGL15::ceIndexBufferGL15 ()
  : name(0)
{
  CE_OBJECT_CONSTR
}

ceIndexBufferGL15::~ceIndexBufferGL15 ()
{
  if (name)
    {
      glDeleteBuffers (1, &name);
    }
}
static inline GLenum ConvertBufferAccessMode (ceBufferAccessMode mode)
{
  switch (mode)
    {
    case BAM_Read:
      return GL_READ_ONLY;
    case BAM_Write:
      return GL_WRITE_ONLY;
    case BAM_ReadWrite:
      return GL_READ_WRITE;
    }
  return GL_READ_WRITE;
}

static inline GLenum ConvertBufferDataMode (ceBufferDataMode mode)
{
  switch (mode)
    {
    case BDM_Dynamic:
      return GL_DYNAMIC_DRAW;
    case BDM_Static:
      return GL_STATIC_DRAW;
    case BDM_Stream:
      return GL_STREAM_DRAW;
    }
  return GL_STATIC_DRAW;
}

bool ceIndexBufferGL15::CreateBuffer (unsigned size, const void* data, ceBufferDataMode mode)
{
  glGenBuffers (1, &name);
  if (name == 0)
    {
      return false;
    }

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, name);
  glBufferData (GL_ELEMENT_ARRAY_BUFFER, size, data, ConvertBufferDataMode(mode));

  return true;
}

bool ceIndexBufferGL15::Copy (unsigned offset, unsigned size, const void* data)
{
  if (name == 0)
    {
      return false;
    }
  glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, name);
  glBufferSubData (GL_ELEMENT_ARRAY_BUFFER, offset, size, data);
  return true;
}

bool ceIndexBufferGL15::Lock (unsigned offset, void** data, ceBufferAccessMode mode)
{
  if (name == 0 || current_mapped_buffer != 0)
    {
      return false;
    }

  void *res = 0;
  glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, name);
  res = glMapBuffer (GL_ELEMENT_ARRAY_BUFFER, ConvertBufferAccessMode(mode));
  if (!res)
    {
      return false;
    }
  current_mapped_buffer = name;
  // now map the offset
  *data = &((char*)res)[offset];
  return true;
}

bool ceIndexBufferGL15::Unlock ()
{
  if (name == 0 || current_mapped_buffer != name)
    {
      return false;
    }

  glUnmapBuffer (GL_ELEMENT_ARRAY_BUFFER);

  current_mapped_buffer = 0;
  return true;
}

void ceIndexBufferGL15::Bind ()
{
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, name);
}
